package com.test.aop;

import com.test.annotation.OperateLog;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @Classname： LogAspect
 * @Description：
 * @Author： xiedong
 * @Date： 2019/11/11 17:27
 * @Version： 1.0
 **/
@Aspect
@Component
@Slf4j
@Order(-1)
public class LogAspect {
    //切点范围
    @Pointcut("@annotation(com.test.annotation.OperateLog)")
    public void operateMethod(){}
    //前置通知
    @Before("operateMethod()")
    public void before(){
        log.info("前置通知：Before");
    }
    //正常返回通知
    @AfterReturning("operateMethod()")
    public void afterReturning(){
        log.info("正常返回通知：AfterReturning");
    }
    //后置通知
    @After("operateMethod()")
    public void after(){
        log.info("后置通知：After");
    }
    //异常返回通知
    @AfterThrowing("operateMethod()")
    public void afterThrowing(){
        log.info("异常返回通知：AfterThrowing");
    }
    //环绕通知
    @Around("operateMethod()")
    public Object methodAround(ProceedingJoinPoint joinPoint) throws Throwable{
        log.info("环绕通知：around------前");
        Object result=null;
        OperateLog annotation = getAnnotation(joinPoint);
        try {
            result=joinPoint.proceed();
        } catch (Throwable throwable) {
            log.info("环绕通知：around------异常");
        }
        try {
            String system = annotation.system();
            int flag = annotation.flag();
            String operatorName = annotation.operatorName();
            log.info("切面校验信息，系统：【{}】,标识:【{}】,操作员名称：【{}】", system,flag,operatorName);
            //日志入库业务
        } catch (Exception e) {
            log.info("切面异常",e);
        }
        log.info("环绕通知：around------后");
        return result;
    }

    private OperateLog getAnnotation(JoinPoint joinPoint){
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        Method method = signature.getMethod();
        return method.getAnnotation(OperateLog.class);
    }
}
